﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CronParse;

namespace MiniScheduler
{
    /// <summary>
    /// 延时队列基础模型
    /// </summary>
    public abstract class TaskItem
    {
        /// <summary>
        /// 队列名称
        /// </summary>
        public string QueueName { get; set; } = Constants.DefaultQueueName;

        /// <summary>
        /// 任务名称
        /// </summary>
        public string TaskName { get; set; } = "Task01";

        /// <summary>
        /// 延时时间
        /// </summary>
        public TimeSpan DelayTime { get; set; }

        /// <summary>
        /// 是否取消， 为true时，不执行
        /// </summary>
        public bool IsCancellation { get; set; }

        /// <summary>
        /// 是否定时任务
        /// </summary>
        public bool IsScheduleTask { get; protected set; }

        /// <summary>
        /// 启用重试
        /// </summary>
        public bool EnableRetry { get; set; }

        /// <summary>
        /// 执行延时回调
        /// </summary>
        public abstract bool? ExecuteAction();
    }

    internal struct DelayQueueKey : IComparable<DelayQueueKey>, IEquatable<DelayQueueKey>
    {
        /// <summary>
        /// 队列名称
        /// </summary>
        public string QueueName { get; set; }

        /// <summary>
        /// 任务名称
        /// </summary>
        public string TaskName { get; set; }

        /// <summary>
        /// 延时时间
        /// </summary>
        public TimeSpan DelayTime { get; set; }

        /// <summary>
        /// 重试次数
        /// </summary>
        public ushort RetryCount { get; set; }

        /// <summary>
        /// 是否定时任务
        /// </summary>
        public bool IsScheduleTask { get; set; }

        /// <summary>
        /// 定时任务表达式
        /// </summary>
        public string CronExpression { get; set; }

        /// <summary>
        /// Cron表达式对象
        /// </summary>
        public CronStruct? Cron { get; set; }

        public int CompareTo(DelayQueueKey other)
        {
            if (IsScheduleTask)
            {
                if (!other.IsScheduleTask)
                {
                    return 1;
                }
                return (CronExpression ?? string.Empty).CompareTo(other.CronExpression ?? string.Empty);
            }
            int eq = this.DelayTime.CompareTo(other.DelayTime);
            if (eq == 0)
            {
                return (this.TaskName ?? string.Empty).CompareTo(other.TaskName ?? string.Empty);
            }
            return eq;
        }

        public bool Equals(DelayQueueKey other)
        {
            if (IsScheduleTask)
            {
                if (!other.IsScheduleTask)
                {
                    return false;
                }
                return string.Equals(this.QueueName, other.QueueName) && string.Equals(this.TaskName, other.TaskName) && string.Equals(this.CronExpression, other.CronExpression);
            }
            return string.Equals(this.QueueName, other.QueueName) && string.Equals(this.TaskName, other.TaskName) && this.DelayTime == other.DelayTime;
        }
    }
}
